#pragma once

#include <iostream>
#include <stdarg.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>


using namespace std;

#define SIZE 1024

//表示不同严重程度
#define Info 0
#define Debug 1
#define Warning 2
#define Error 3
#define Fatal 4

#define Screen 1 //打印到屏幕
#define Onefile 2 //所有日志写入同一个文件
#define Classfile 3 //按日志级别分文件

#define LogFile "log.txt"

class Log {
public:
    //默认输出到屏幕，日志目录为 ./log/
    Log() { 
        printMethod = Screen; 
        path = "./log/";
    }
    void Enable(int method) { printMethod = method; } //设置日志输出方式

    string levelToString(int level) { //把数字型的日志级别 → 转成人类可读的字符串
        switch (level) {
        case Info: return "Info";
        case Debug: return "Debug";
        case Warning: return "Warning";
        case Error: return "Error";
        case Fatal: return "Fatal";
        default: return "None";    
        }
    }

    void printLog(int level, const string& logtxt) { //根据 printMethod 的值决定日志去哪
        switch (printMethod) {
        case Screen:
            cout << logtxt << endl;
            break;
        case Onefile:
            printOneFile(LogFile, logtxt);
            break;
        case Classfile:
            printClassFile(level, logtxt);
            break;
        default:
            break;
        }
    }

    void printOneFile(const string& logname, const string& logtxt) {
        string _logname = path + logname;
        int fd = open(_logname.c_str(), O_WRONLY|O_CREAT|O_APPEND, 0666);
        if (fd < 0 ) return;
        write(fd, logtxt.c_str(), logtxt.size());
        close(fd);
    }

    void printClassFile(int level, const string& logtxt) {
        string filename = LogFile;
        filename += ".";
        filename += levelToString(level);
        printOneFile(filename, logtxt);
    }

    void operator()(int level, const char* format, ...) {
        //获取当前时间 → 格式化到 leftbuffer
        time_t t = time(nullptr);
        struct tm* ctime = localtime(&t);
        
        char leftbuffer[SIZE];
        snprintf(leftbuffer, sizeof(leftbuffer), "[%s][%d-%d-%d %d:%d:%d]", levelToString(level).c_str(),
        ctime->tm_year+1900, ctime->tm_mon+1, ctime->tm_mday, ctime->tm_hour, ctime->tm_min, ctime->tm_sec);

        //处理用户传入的可变参数 → 格式化到 rightbuffer
        va_list s;
        va_start(s, format);
        char rightbuffer[SIZE];
        vsnprintf(rightbuffer, sizeof(rightbuffer), format, s);
        va_end(s);

        //拼接成完整日志字符串
        char logtxt[SIZE*2];
        snprintf(logtxt, sizeof(logtxt), "%s %s", leftbuffer, rightbuffer);
        //格式：默认部分+自定义部分

        // printf("%s", logtxt);
        printLog(level, logtxt);    
    }

    ~Log() {}
private:
    int printMethod;
    string path;
};

Log lg;